//
//  PSGameSettings.m
//  PrefCore
//
//  Created by Sergey on 1/25/14.
//  Copyright (c) 2014 Play-on-smart. All rights reserved.
//

#import "PSGameSettings.h"

enum {
    kPassingInterruptedBySuccessfulMisere
,   kPassingInterruptedByNonWhistedGame
,   kPassingInterruptedByFailedGame
,   kPassingInterruptedByFailedMisere
,   kPassingInterruptedMax
};

#define INITIAL_POOL_SIZE 20

@interface PSGameSettings () {
    BOOL passingInterruptions[kPassingInterruptedMax];
    PSGameLevel levels[2];
}

@end

static NSString* udKeyPoolSize = @"poolSize";
static NSString* udKeyGameFlavor = @"gameFlavor";
static NSString* udKeyPassingType = @"passingType";
static NSString* udKeyPassingProgression = @"passingProgression";
static NSString* udKeyPassingTrickCost = @"passingTrickCost";
static NSString* udKeyPassingExit = @"passingExit";
static NSString* udKeyMisereCatchMode = @"misereCatchMode";
static NSString* udKeyTrickingTen = @"trickingTen";
static NSString* udKeyWhistType = @"whistType";
static NSString* udKeyMandatoryWhistOnSixSpades = @"mandatoryWhistOnSixSpades";
static NSString* udKeySuitOrder = @"suitOrder";
static NSString* udKeyRankOrder = @"rankOrder";
static NSString* udKeySpaceBetweenSuits = @"spaceBetweenSuits";
static NSString* udKeyBidConfirmation = @"bidConfirmation";
static NSString* udKeyContractConfirmation = @"contractConfirmation";
static NSString* udKeyRoundEndTapWhenNotPlaying = @"roundEndTapWhenNotPlaying";
static NSString* udKeyRoundEndTapWhenLastMoverAi = @"roundEndTapWhenLastMoverAi";
static NSString* udKeyRoundEndTapWhenLastMoverHuman = @"roundEndTapWhenLastMoverHuman";
static NSString* udKeyAutomateObviousMoves = @"automateObviousMoves";
static NSString* udKeySkipGameOnPass = @"skipGameOnPass";
static NSString* udKeyPassingInterruptionsSuccessfulMisere = @"passingInterruptSuccessfulMisere";
static NSString* udKeyPassingInterruptionsNonWhistedGame = @"passingInterruptNonWhistedGame";
static NSString* udKeyPassingInterruptionsFailedGame = @"passingInterruptFailedGame";
static NSString* udKeyPassingInterruptionsFailedMisere = @"passingInterruptFailedMisere";
static NSString* udKeyLevelOfUser0 = @"levelOfUser0";
static NSString* udKeyLevelOfUser1 = @"levelOfUser1";

@implementation PSGameSettings

-(instancetype)init {
    if (self = [super init]) {
        _poolSize = INITIAL_POOL_SIZE;
        _gameFlavor = kGameFlavorSochi;
        _passingType = kPassingTypeSliding;
        _passingProgression =  kPassingProgression_123123;
        _passingTrickCost = kPassingTrickCost_1;
        _passingExit = kPassingExit_6777;
        _misereCatchMode = kMisereCacthModeDefault;
        _trickingTen = kTricking10Checked;
        _whistType = kWhistGreedy;
        _mandatoryWhistOnSixSpades = YES;
        _suitOrder = kSuitOrderByColor;
        _rankOrder = kRankOrderAscending;
        _spaceBetweenSuits = NO;
        _bidConfirmation = kConfirmationAlways;
        _contractConfirmation = kConfirmationAlways;
        _roundEndTapWhenNotPlaying = YES;
        _roundEndTapWhenLastMoverAi = YES;
        _roundEndTapWhenLastMoverHuman = NO;
        _automateObviousMoves = NO;
        _skipGameOnPass = NO;
        passingInterruptions[kPassingInterruptedBySuccessfulMisere] = NO;
        passingInterruptions[kPassingInterruptedByNonWhistedGame] = NO;
        passingInterruptions[kPassingInterruptedByFailedGame] = NO;
        passingInterruptions[kPassingInterruptedByFailedMisere] = NO;
        levels[0] = kGameLevel0;
        levels[1] = kGameLevel0;
    }
    return self;
}

+(instancetype)settingsFromUserDefaults:(NSUserDefaults*)ud {
    PSGameSettings *res = [[PSGameSettings alloc] init];
    if (ud) {
        if ([ud objectForKey:udKeyPoolSize]) {
            res->_poolSize = (int)[ud integerForKey:udKeyPoolSize];
        }
        if ([ud objectForKey:udKeyGameFlavor]) {
        res->_gameFlavor = (PSGameFlavor)[ud integerForKey:udKeyGameFlavor];
        }
        if ([ud objectForKey:udKeyPassingType]) {
            res->_passingType = (PSGamePassingType)[ud integerForKey:udKeyPassingType];
        }
        if ([ud objectForKey:udKeyPassingProgression]) {
            res->_passingProgression = (PSGamePassingProgression)[ud integerForKey:udKeyPassingProgression];
        }
        if ([ud objectForKey:udKeyPassingTrickCost]) {
            res->_passingTrickCost = (PSGamePassingTrickCost)[ud integerForKey:udKeyPassingTrickCost];
        }
        if ([ud objectForKey:udKeyPassingExit]) {
            res->_passingExit = (PSGamePassingExit)[ud integerForKey:udKeyPassingExit];
        }
        if ([ud objectForKey:udKeyMisereCatchMode]) {
            res->_misereCatchMode = (PSGameMisereCacthMode)[ud integerForKey:udKeyMisereCatchMode];
        }
        if ([ud objectForKey:udKeyTrickingTen]) {
            res->_trickingTen = (PSGameTricking10)[ud integerForKey:udKeyTrickingTen];
        }
        if ([ud objectForKey:udKeyWhistType]) {
            res->_whistType = (PSGameWhistType)[ud integerForKey:udKeyWhistType];
        }
        if ([ud objectForKey:udKeyMandatoryWhistOnSixSpades]) {
            res->_mandatoryWhistOnSixSpades = [ud boolForKey:udKeyMandatoryWhistOnSixSpades];
        }
        if ([ud objectForKey:udKeySuitOrder]) {
            res->_suitOrder = (PSGameSuitOrder)[ud integerForKey:udKeySuitOrder];
        }
        if ([ud objectForKey:udKeyRankOrder]) {
            res->_rankOrder = (PSGameRankOrder)[ud integerForKey:udKeyRankOrder];
        }
        if ([ud objectForKey:udKeySpaceBetweenSuits]) {
            res->_spaceBetweenSuits = [ud boolForKey:udKeySpaceBetweenSuits];
        }
        if ([ud objectForKey:udKeyBidConfirmation]) {
            res->_bidConfirmation = (PSGameConfirmation)[ud integerForKey:udKeyBidConfirmation];
        }
        if ([ud objectForKey:udKeyContractConfirmation]) {
            res->_contractConfirmation = (PSGameConfirmation)[ud integerForKey:udKeyContractConfirmation];
        }
        if ([ud objectForKey:udKeyRoundEndTapWhenNotPlaying]) {
            res->_roundEndTapWhenNotPlaying = [ud boolForKey:udKeyRoundEndTapWhenNotPlaying];
        }
        if ([ud objectForKey:udKeyRoundEndTapWhenLastMoverAi]) {
            res->_roundEndTapWhenLastMoverAi = [ud boolForKey:udKeyRoundEndTapWhenLastMoverAi];
        }
        if ([ud objectForKey:udKeyRoundEndTapWhenLastMoverHuman]) {
            res->_roundEndTapWhenLastMoverHuman = [ud boolForKey:udKeyRoundEndTapWhenLastMoverHuman];
        }
        if ([ud objectForKey:udKeyAutomateObviousMoves]) {
            res->_automateObviousMoves = [ud boolForKey:udKeyAutomateObviousMoves];
        }
        if ([ud objectForKey:udKeySkipGameOnPass]) {
            res->_skipGameOnPass = [ud boolForKey:udKeySkipGameOnPass];
        }
        if ([ud objectForKey:udKeyPassingInterruptionsSuccessfulMisere]) {
            res->passingInterruptions[kPassingInterruptedBySuccessfulMisere] =
                [ud boolForKey:udKeyPassingInterruptionsSuccessfulMisere];
        }
        if ([ud objectForKey:udKeyPassingInterruptionsNonWhistedGame]) {
            res->passingInterruptions[kPassingInterruptedByNonWhistedGame] =
                [ud boolForKey:udKeyPassingInterruptionsNonWhistedGame];
        }
        if ([ud objectForKey:udKeyPassingInterruptionsFailedGame]) {
            res->passingInterruptions[kPassingInterruptedByFailedGame] =
                [ud boolForKey:udKeyPassingInterruptionsFailedGame];
        }
        if ([ud objectForKey:udKeyPassingInterruptionsFailedMisere]) {
            res->passingInterruptions[kPassingInterruptedByFailedMisere] =
                [ud boolForKey:udKeyPassingInterruptionsFailedMisere];
        }
        if ([ud objectForKey:udKeyLevelOfUser0]) {
            res->levels[0] = (PSGameLevel)[ud integerForKey:udKeyLevelOfUser0];
        }
        if ([ud objectForKey:udKeyLevelOfUser1]) {
            res->levels[1] = (PSGameLevel)[ud integerForKey:udKeyLevelOfUser1];
        }
    }
    return res;
}

-(void)saveToUserDefaults:(NSUserDefaults*)ud {
    [ud setInteger:_poolSize forKey:udKeyPoolSize];
    [ud setInteger:_gameFlavor forKey:udKeyGameFlavor];
    [ud setInteger:_passingType forKey:udKeyPassingType];
    [ud setInteger:_passingProgression forKey:udKeyPassingProgression];
    [ud setInteger:_passingTrickCost forKey:udKeyPassingTrickCost];
    [ud setInteger:_passingExit forKey:udKeyPassingExit];
    [ud setInteger:_misereCatchMode forKey:udKeyMisereCatchMode];
    [ud setInteger:_trickingTen forKey:udKeyTrickingTen];
    [ud setInteger:_whistType forKey:udKeyWhistType];
    [ud setBool:_mandatoryWhistOnSixSpades forKey:udKeyMandatoryWhistOnSixSpades];
    [ud setInteger:_suitOrder forKey:udKeySuitOrder];
    [ud setInteger:_rankOrder forKey:udKeyRankOrder];
    [ud setBool:_spaceBetweenSuits forKey:udKeySpaceBetweenSuits];
    [ud setInteger:_bidConfirmation forKey:udKeyBidConfirmation];
    [ud setInteger:_contractConfirmation forKey:udKeyContractConfirmation];
    [ud setBool:_roundEndTapWhenNotPlaying forKey:udKeyRoundEndTapWhenNotPlaying];
    [ud setBool:_roundEndTapWhenLastMoverAi forKey:udKeyRoundEndTapWhenLastMoverAi];
    [ud setBool:_roundEndTapWhenLastMoverHuman forKey:udKeyRoundEndTapWhenLastMoverHuman];
    [ud setBool:_automateObviousMoves forKey:udKeyAutomateObviousMoves];
    [ud setBool:_skipGameOnPass forKey:udKeySkipGameOnPass];
    [ud setBool:passingInterruptions[kPassingInterruptedBySuccessfulMisere]
         forKey:udKeyPassingInterruptionsSuccessfulMisere];
    [ud setBool:passingInterruptions[kPassingInterruptedByNonWhistedGame]
         forKey:udKeyPassingInterruptionsNonWhistedGame];
    [ud setBool:passingInterruptions[kPassingInterruptedByFailedGame]
         forKey:udKeyPassingInterruptionsFailedGame];
    [ud setBool:passingInterruptions[kPassingInterruptedByFailedMisere]
         forKey:udKeyPassingInterruptionsFailedMisere];
    [ud setInteger:levels[0] forKey:udKeyLevelOfUser0];
    [ud setInteger:levels[1] forKey:udKeyLevelOfUser1];
}

+(void)clearUserDefaults:(NSUserDefaults*)ud {
    [ud removeObjectForKey:udKeyPoolSize];
    [ud removeObjectForKey:udKeyGameFlavor];
    [ud removeObjectForKey:udKeyPassingType];
    [ud removeObjectForKey:udKeyPassingProgression];
    [ud removeObjectForKey:udKeyPassingTrickCost];
    [ud removeObjectForKey:udKeyPassingExit];
    [ud removeObjectForKey:udKeyMisereCatchMode];
    [ud removeObjectForKey:udKeyTrickingTen];
    [ud removeObjectForKey:udKeyWhistType];
    [ud removeObjectForKey:udKeyMandatoryWhistOnSixSpades];
    [ud removeObjectForKey:udKeySuitOrder];
    [ud removeObjectForKey:udKeyRankOrder];
    [ud removeObjectForKey:udKeySpaceBetweenSuits];
    [ud removeObjectForKey:udKeyBidConfirmation];
    [ud removeObjectForKey:udKeyContractConfirmation];
    [ud removeObjectForKey:udKeyRoundEndTapWhenNotPlaying];
    [ud removeObjectForKey:udKeyRoundEndTapWhenLastMoverAi];
    [ud removeObjectForKey:udKeyRoundEndTapWhenLastMoverHuman];
    [ud removeObjectForKey:udKeyAutomateObviousMoves];
    [ud removeObjectForKey:udKeySkipGameOnPass];
    [ud removeObjectForKey:udKeyPassingInterruptionsSuccessfulMisere];
    [ud removeObjectForKey:udKeyPassingInterruptionsNonWhistedGame];
    [ud removeObjectForKey:udKeyPassingInterruptionsFailedGame];
    [ud removeObjectForKey:udKeyPassingInterruptionsFailedMisere];
    [ud removeObjectForKey:udKeyLevelOfUser0];
    [ud removeObjectForKey:udKeyLevelOfUser1];
}

-(BOOL)isPassingInterruptedByMisereWithTricks:(PSTrickCount)tricks {
    return !tricks
        ?   passingInterruptions[kPassingInterruptedBySuccessfulMisere]
        :   passingInterruptions[kPassingInterruptedByFailedMisere];
}

-(BOOL)isPassingInterruptedByNonWhistedGame {
    return passingInterruptions[kPassingInterruptedByNonWhistedGame];
}

-(BOOL)isPassingInterruptedByFailedGame; {
    return passingInterruptions[kPassingInterruptedByFailedGame];
}

-(PSGameLevel)levelForPlayerId:(int)playerId {
    NSAssert(playerId == 1 || playerId == 2, @"Player id in levelForPlayerId: must be one or two.");
    return levels[playerId-1];
}

-(void)setLevel:(PSGameLevel)level forPlayerId:(int)playerId {
    NSAssert(playerId == 1 || playerId == 2, @"Player id in levelForPlayerId: must be one or two.");
    levels[playerId-1] = level;
}

@end
